package com.ctvit.cch.core.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctvit.cch.core.mapper.HotRecordMapper;
import com.ctvit.cch.core.pojo.domain.HotRecord;
import com.ctvit.cch.core.pojo.domain.SocialPlatform;
import com.ctvit.cch.core.pojo.dto.HotRecordAddDTO;
import com.ctvit.cch.core.pojo.dto.HotRecordEditDTO;
import com.ctvit.cch.core.pojo.dto.HotRecordListDTO;
import com.ctvit.cch.core.pojo.vo.HotCategoryRecordVO;
import com.ctvit.cch.core.pojo.vo.HotRecordGetVO;
import com.ctvit.cch.core.pojo.vo.HotRecordListVO;
import com.ctvit.cch.core.service.IHotCategoryService;
import com.ctvit.cch.core.service.IHotRecordService;
import com.ctvit.cch.core.service.ISocialPlatformService;
import com.ctvit.cch.core.utils.NumberConvertUtils;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.page.TableDataInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 热榜数据Service业务层处理
 *
 * @author heyingcheng
 * @date 2025/07/27
 */
@Slf4j
@Service
public class HotRecordServiceImpl extends ServiceImpl<HotRecordMapper, HotRecord> implements IHotRecordService {

    private final ISocialPlatformService socialPlatformService;

    private final IHotCategoryService hotCategoryService;

    public HotRecordServiceImpl(ISocialPlatformService socialPlatformService, IHotCategoryService hotCategoryService) {
        this.socialPlatformService = socialPlatformService;
        this.hotCategoryService = hotCategoryService;
    }

    @Override
    public TableDataInfo list(HotRecordListDTO dto) {
        Map<String, SocialPlatform> platformMap = socialPlatformService.list().stream().collect(Collectors.toMap(SocialPlatform::getPlatformId, Function.identity()));
        Map<Integer, String> categoryMap = hotCategoryService.record().stream().collect(Collectors.toMap(HotCategoryRecordVO::getCategoryId, HotCategoryRecordVO::getCategoryName));

        LambdaQueryWrapper<HotRecord> qWrapper = new LambdaQueryWrapper<>();
        qWrapper.eq(StringUtils.isNotBlank(dto.getPlatformId()), HotRecord::getPlatformId, dto.getPlatformId());
        qWrapper.eq(StringUtils.isNotBlank(dto.getCategoryId()), HotRecord::getCategoryId, dto.getCategoryId());
        qWrapper.like(StringUtils.isNotBlank(dto.getTitle()), HotRecord::getTitle, dto.getTitle());
        qWrapper.like(StringUtils.isNotBlank(dto.getRecommendation()), HotRecord::getRecommendation, dto.getRecommendation());
        qWrapper.eq(HotRecord::getStatus, NumberUtils.INTEGER_ZERO.toString());
        qWrapper.orderByDesc(HotRecord::getUpdateTime);
        qWrapper.orderByDesc(HotRecord::getScore);

        Page<HotRecord> page = page(new Page<>(dto.getPageNum(), dto.getPageSize()), qWrapper);

        List<HotRecordListVO> records = page.getRecords().stream().map(t -> {
            HotRecordListVO v = new HotRecordListVO();
            BeanUtils.copyProperties(t, v);
            SocialPlatform socialPlatform = platformMap.get(t.getPlatformId());
            v.setPlatformName(socialPlatform.getPlatformName());
            v.setPlatformIcon(socialPlatform.getPlatformIcon());
            v.setCategoryName(categoryMap.get(t.getCategoryId()));
            return v;
        }).collect(Collectors.toList());

        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setRows(records);
        tableDataInfo.setTotal(page.getTotal());

        return tableDataInfo;
    }

    @Override
    public boolean add(HotRecordAddDTO dto) {
        HotRecord entity = new HotRecord();
        BeanUtils.copyProperties(dto, entity);
        entity.setRecordId(IdWorker.getIdStr());
        return save(entity);
    }

    @Override
    public boolean edit(HotRecordEditDTO dto) {
        HotRecord entity = new HotRecord();
        BeanUtils.copyProperties(dto, entity);
        return updateById(entity);
    }

    @Override
    public HotRecordGetVO get(String id) {
        HotRecordGetVO target = new HotRecordGetVO();
        BeanUtils.copyProperties(getById(id), target);
        return target;
    }

    @Override
    public List<HotRecord> listByStatus(String status) {
        LambdaQueryWrapper<HotRecord> qWrapper = new LambdaQueryWrapper<>();
        qWrapper.eq(HotRecord::getStatus, status);
        qWrapper.orderByDesc(HotRecord::getCreateTime);
        qWrapper.last("LIMIT 10");
        return list(qWrapper);
    }

    @Override
    public boolean collect(String platformName) {
        switch (platformName) {
            case "抖音":
                return collectDouYin();
            case "快手":
                return collectKuaishou();
            case "好看视频":
                return collectHaoKan();
            case "哔哩哔哩":
                return collectBiliBili();
            default:
                return false;
        }
    }

    private boolean collectDouYin() {
        // 构建请求 URL
        String url = "https://www.douyin.com/aweme/v1/web/hot/search/list/?device_platform=webapp&aid=6383&channel=channel_pc_web&detail_list=1&source=6&main_billboard_count=5&update_version_code=170400&pc_client_type=1&pc_libra_divert=Windows&support_h265=1&support_dash=1&cpu_core_num=32&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1920&screen_height=1080&browser_language=zh-CN&browser_platform=Win32&browser_name=Smart+Lenovo+Browser&browser_version=9.0.6.7021&browser_online=true&engine_name=Blink&engine_version=124.0.0.0&os_name=Windows&os_version=10&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=250&webid=7532759076352067107&uifid=c6c0c2228051f46ee37f8d31df16d4bc5c6e10a5c5bc5e81978af04133dce10be1f2c98f74e6ecd729399ec177600f090e08b7f75db8b062d5556c5442739ccd0a93090eeeb5d3e90cf5a811b7a0b0b244e47f74391a1bcd1be161872eb356c19c2f885bd67542dd26d111e8d55146bd6b34221cf7a1260f84fae9447732eb5981108b26943765de83cc31530b7b5202be29716e57c11c0731fa1553fb20ec89&msToken=bHV16L9JoG8ey220WOcT3GNe3JAAAUHlad4PCvbMM1XWYDC3u6Pb70p4O4USFdof18S39OVrpSkQCnRASKQdAIiPXG_ZFY2Yw3yWVInpuFzIkAiCqn1m8uNyM-miYcTCizvgtNCMj2mtI30v4qboL-AToyll2WXx4d2d2sO--1av5iyfsF3P&a_bogus=D64nDwXLDNW5CdFGYKa7tVMlNo6lrTySpZTxWPxPtOT7OwtYiSNCixCPJoq60Q6L08Biio3HBDeMYxdcTsXwZerkKmpkSkTbF459VWvLgqisYUTBDq8kegkzqw0r0Oswe5VtiAU6ZUHH6nVAirdm%2FpA99KLeQb8BP1OSkZzbY9BgZF6ALpc1PdSZYwGqVE%3D%3D&verifyFp=verify_mdpl9teg_vhC7RE4T_B4aH_4pI5_8OXF_dUGdjpiY2KGR&fp=verify_mdpl9teg_vhC7RE4T_B4aH_4pI5_8OXF_dUGdjpiY2KGR";
        HttpRequest httpRequest = HttpRequest.get(url)
                .header("cookie", "enter_pc_once=1; UIFID_TEMP=c6c0c2228051f46ee37f8d31df16d4bc5c6e10a5c5bc5e81978af04133dce10be1f2c98f74e6ecd729399ec177600f09d32c6a6a3d5dbc49315ef94571dde3a7f8551190f9e371f4f8fd0e4b310cef0e; hevc_supported=true; WebUgChannelId=%2230006%22; s_v_web_id=verify_mdpl9teg_vhC7RE4T_B4aH_4pI5_8OXF_dUGdjpiY2KGR; fpk1=U2FsdGVkX1+RWbLv0VuFORagiaUO4wW8Ks19alnZLfkdct2qvsU/EgYNLUROYb4jvTQqIPqxP/fplN0d3UuLUg==; fpk2=fa4fadc094f165eca76b3b0b157369e9; strategyABtestKey=%221753857165.333%22; passport_csrf_token=2d2f33ab22b40b0ee5bb35858d21fc15; passport_csrf_token_default=2d2f33ab22b40b0ee5bb35858d21fc15; xgplayer_user_id=556459828452; bd_ticket_guard_client_web_domain=2; __security_mc_1_s_sdk_crypt_sdk=7e5e04e4-42cc-aa3c; __security_mc_1_s_sdk_cert_key=73c6f87d-4f6c-8eda; __security_mc_1_s_sdk_sign_data_key_web_protect=53622dd3-4251-a446; odin_tt=2659daae3a81ce566ead596ef5aeef3764a70d631a04f8b27b77693ee0baff80abf2502fcd66cab958bcc6267e3ed74f99adf9e0fe0f87e3be232970d58daae508d679128dbad965bf7ab1642cd3d729; UIFID=c6c0c2228051f46ee37f8d31df16d4bc5c6e10a5c5bc5e81978af04133dce10be1f2c98f74e6ecd729399ec177600f090e08b7f75db8b062d5556c5442739ccd0a93090eeeb5d3e90cf5a811b7a0b0b244e47f74391a1bcd1be161872eb356c19c2f885bd67542dd26d111e8d55146bd6b34221cf7a1260f84fae9447732eb5981108b26943765de83cc31530b7b5202be29716e57c11c0731fa1553fb20ec89; ttwid=1%7CjvXkQTOcM8I46Qu_Ta0-Ec7xYVgTXgrrjVsKnOdCung%7C1753858878%7C179d2866be5d0fdfd0035ae99e75fcc12a8dddc2082e64ed57a56afbfe72f94b; is_dash_user=1; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCRm5GdW5EelEvTWd5aGhVWEMrZEY4V05VOE5KQm9PZ1pYMmEveEt5YlIxdnlhVVhwRmY5SzhlN1RLMzMyZkNheHFmOWRIWExtK3ZDbWtneVVHanprTk09IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.5%7D; __ac_nonce=0688b24c2009dc6918b6f; __ac_signature=_02B4Z6wo00f016BtT0AAAIDAncRV33Rv.YOgTUvAAICYd3; douyin.com; xg_device_score=7.857138956336412; device_web_cpu_core=32; device_web_memory_size=8; architecture=amd64; home_can_add_dy_2_desktop=%220%22; dy_swidth=1920; dy_sheight=1080; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1920%2C%5C%22screen_height%5C%22%3A1080%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A32%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A250%7D%22; download_guide=%221%2F20250731%2F0%22; stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A1%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22; IsDouyinActive=true")
                .header("uifid", "c6c0c2228051f46ee37f8d31df16d4bc5c6e10a5c5bc5e81978af04133dce10be1f2c98f74e6ecd729399ec177600f090e08b7f75db8b062d5556c5442739ccd0a93090eeeb5d3e90cf5a811b7a0b0b244e47f74391a1bcd1be161872eb356c19c2f885bd67542dd26d111e8d55146bd6b34221cf7a1260f84fae9447732eb5981108b26943765de83cc31530b7b5202be29716e57c11c0731fa1553fb20ec89").header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 SLBrowser/9.0.6.7021 SLBChan/ SLBVPV/64-bit")
                .header("accept", "application/json, text/plain, */*")
                .header("accept-language", "zh-CN,zh;q=0.9")
                .header("priority", "u=1, i")
                .header("referer", "https://www.douyin.com/?recommend=1")
                .header("sec-ch-ua", "\"Chromium\";v=\"9\", \"Not?A_Brand\";v=\"8\"")
                .header("sec-ch-ua-mobile", "?0")
                .header("sec-ch-ua-platform", "\"Windows\"")
                .header("sec-fetch-dest", "empty")
                .header("sec-fetch-mode", "cors")
                .header("sec-fetch-site", "same-origin")
                .timeout(30000);

        try (HttpResponse response = httpRequest.execute()) {
            int status = response.getStatus();
            String body = response.body();

            log.info("请求抖音热搜接口，状态码:[{}], 响应内容:[{}]", status, body);
            JSONObject bodyJsonObject = JSON.parseObject(body);
            if (NumberUtils.INTEGER_ZERO.equals(bodyJsonObject.getInteger("status_code"))) {
                JSONArray wordJsonArray = (JSONArray) bodyJsonObject.getByPath("data.word_list");
                for (int i = 0, size = wordJsonArray.size(); i < size; i++) {
                    JSONObject wordJsonObject = wordJsonArray.getJSONObject(i);
                    long score = wordJsonObject.getLongValue("hot_value");
                    if (score > 0) {
                        String keyword = wordJsonObject.getString("word");
                        Integer rank = wordJsonObject.getInteger("position");
                        String link = String.format("https://www.douyin.com/root/search/%s?aid=1457c694-ce68-4027-b58d-f63bd516cfcd&type=general&ug_source=pc_liangxiang_01", URLEncoder.encode(keyword, StandardCharsets.UTF_8));
                        String image = wordJsonObject.getByPath("word_cover.url_list[0]").toString();

                        assignHotRecord("1949738586847244290", keyword, keyword, link, score, rank, image, wordJsonObject.toString());
                    }
                }
            }
            return status == 200;
        } catch (Exception e) {
            log.error("请求抖音热搜接口失败", e);
            return false;
        }
    }

    private boolean collectKuaishou() {
        String url = "https://www.kuaishou.com/graphql";

        // 构建请求体
        String requestBody = "{\"operationName\":\"hotRankQuery\",\"variables\":{\"page\":\"home\"},\"query\":\"query hotRankQuery($page: String) {\\n  visionHotRank(page: $page) {\\n    result\\n    pcursor\\n    webPageArea\\n    items {\\n      rank\\n      id\\n      name\\n      viewCount\\n      hotValue\\n      iconUrl\\n      poster\\n      tagType\\n      photoIds\\n      __typename\\n    }\\n    __typename\\n  }\\n}\\n\"}";

        HttpRequest httpRequest = HttpRequest.post(url)
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("Connection", "keep-alive")
                .header("Origin", "https://www.kuaishou.com")
                .header("Referer", "https://www.kuaishou.com/?isHome=1")
                .header("Sec-Fetch-Dest", "empty")
                .header("Sec-Fetch-Mode", "cors")
                .header("Sec-Fetch-Site", "same-origin")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0")
                .header("accept", "*/*")
                .header("sec-ch-ua", "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"")
                .header("sec-ch-ua-mobile", "?0")
                .header("sec-ch-ua-platform", "\"Windows\"")
                .header("Cookie", "kpf=PC_WEB; clientid=3; did=web_8b1f600d2789db4e925c5e517431968a; kwfv1=PnGU+9+Y8008S+nH0U+0mjPf8fP08f+98f+nLlwnrIP9+Sw/ZFGfzY+eGlGf+f+e4SGfbYP0QfGnLFwBLU80mYGAzY8ecM+9HAwe8fP9cU+eGAPeLFwnHh80cEG/8YweHl+/cMweGUPnG78/HF8fzYwnb0PeWE8ec9P08SGfQY+AZFP0Wh+fHlP0PF+BPMPfbSP/mfP/qFG/rI+0DU+nbjPc==; kpn=KUAISHOU_VISIO")
                .header("content-type", "application/json")
                .body(requestBody)
                .timeout(30000);

        try (HttpResponse response = httpRequest.execute()) {
            int status = response.getStatus();
            String body = response.body();

            log.info("请求快手热搜接口，状态码:[{}], 响应内容:[{}]", status, body);

            if (status == 200) {
                JSONObject bodyJsonObject = JSON.parseObject(body);
                JSONObject visionHotRank = bodyJsonObject.getJSONObject("data").getJSONObject("visionHotRank");

                if (visionHotRank != null) {
                    JSONArray items = visionHotRank.getJSONArray("items");

                    for (int i = 0; i < items.size(); i++) {
                        JSONObject itemsJsonObject = items.getJSONObject(i);
                        long score = NumberConvertUtils.convertToLong(itemsJsonObject.getString("hotValue"));
                        if (score > 0) {
                            String keyword = itemsJsonObject.getString("name");
                            String link = String.format("https://www.kuaishou.com/search/video?searchKey=%s", URLEncoder.encode(keyword, StandardCharsets.UTF_8));
                            Integer rank = itemsJsonObject.getInteger("rank");
                            String image = itemsJsonObject.getString("poster");

                            assignHotRecord("1952265235551653890", keyword, keyword, link, score, rank, image, itemsJsonObject.toString());
                        }
                    }
                }
            }

            return status == 200;
        } catch (Exception e) {
            log.error("请求快手热搜接口失败", e);
            return false;
        }
    }

    private boolean collectHaoKan() {
        String url = "https://haokan.baidu.com/videoui/page/pc/toplist?type=hotvideo&sfrom=haokan_web_banner&pageSize=20&_format=json&page=1";

        HttpRequest httpRequest = HttpRequest.get(url)
                .header("Accept", "*/*")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("Cache-Control", "no-cache")
                .header("Connection", "keep-alive")
                .header("Content-Type", "application/x-www-form-urlencoded")
                .header("Cookie", "PSTM=1754294900; BAIDUID=C25B447B65323ADBA41BC31B05C71DDF:FG=1; BAIDUID_BFESS=C25B447B65323ADBA41BC31B05C71DDF:FG=1; BIDUPSID=322ED5A386486E933B2C5E52A888F45B; BA_HECTOR=8k0ga524ak0h800k0g002h0h840g0h1k90qjr25; ZFY=Lijs9aA:B55eiMKLP4lrRK1ysgpCjQdnbjMo:BgdJvvVM:C; H_PS_PSSID=60274_62325_63144_63881_63948_64020_64092_64125_64138_64143_64161_64174_64183_64219_64248_64246_64251_64258_64260_64294_64318_64366_64362_64363_64372; delPer=0; PSINO=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_WISE_SIDS=60274_62325_63144_63881_63948_64092_64125_64138_64143_64161_64174_64183_64219_64248_64246_64251_64258_64260_64294_64318_64366_64362_64363_64372; Hm_lvt_4aadd610dfd2f5972f1efee2653a2bc5=1754294913; HMACCOUNT=A580C1349C7C5CD1; arialoadData=false; ab_sr=1.0.1_MGY4NjI3MDI1OGI1YzM4NWIwYWUyYTFjYmRhMDFmZWU2YzU2NjMzOGJhYTk2NjNmZDk3YjA3MDg5NjM0ZTE4YzJjNTgyYTk1OGFjNzk0MmQyZjBkMmRiMTI0Y2MyMjkxMjYxMDBkMmQ4ZjdhYTM0YjE0MGM3ZmZmZTAzMGU2YzA4YTYxMzhiZmI0YzExYTJhZGE0NDU4YTAzMTBhMmFjYw==; reptileData=%7B%22data%22%3A%22856f28aab0e9fd4d26b4ca9ce8d2827bb48d19ed8a0fd57cb54e2e936b437d12b41fffe0a8070f6ea6e950155becdad38d742c9ff8109e4c1845ca321de7b7fda984b751e3c9d7f8b1df3d4852c384840d2d87d3c71e7ba25b7890935b8532ad%22%2C%22key_id%22%3A%2230%22%2C%22sign%22%3A%222d0741ed%22%7D; Hm_lpvt_4aadd610dfd2f5972f1efee2653a2bc5=1754294933; RT=\"z=1&dm=baidu.com&si=b166706e-6043-4ea4-94ff-eede493ef827&ss=mdwvmtfr&sl=1&tt=cg&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=e2\"")
                .header("Referer", "https://haokan.baidu.com/")
                .header("Sec-Fetch-Dest", "empty")
                .header("Sec-Fetch-Mode", "cors")
                .header("Sec-Fetch-Site", "same-origin")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0")
                .header("sec-ch-ua", "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"")
                .header("sec-ch-ua-mobile", "?0")
                .header("sec-ch-ua-platform", "\"Windows\"")
                .timeout(30000);

        try (HttpResponse response = httpRequest.execute()) {
            int status = response.getStatus();
            String body = response.body();

            log.info("请求好看视频热搜接口，状态码:[{}], 响应内容长度:[{}]", status, body.length());

            if (status == 200) {
                JSONObject bodyJsonObject = JSON.parseObject(body);
                if (NumberUtils.INTEGER_ZERO.equals(bodyJsonObject.getInteger("errno"))) {
                    JSONArray wordJsonArray = (JSONArray) bodyJsonObject.getByPath("apiData.response.video");
                    for (int i = 0; i < wordJsonArray.size(); i++) {
                        JSONObject videoJsonObject = wordJsonArray.getJSONObject(i);
                        long score = NumberConvertUtils.convertToLong(videoJsonObject.getString("hot"));
                        if (score > 0) {
                            String keyword = videoJsonObject.getString("title");
                            String link = videoJsonObject.getString("pageUrl");
                            String image = videoJsonObject.getString("poster");
                            Integer rank = i + 1; // 好看视频没有直接提供排名，使用索引+1作为排名

                            assignHotRecord("1952292195535372289", keyword, keyword, link, score, rank, image, videoJsonObject.toString());
                        }
                    }
                }
            }

            return status == 200;
        } catch (Exception e) {
            log.error("请求好看视频热搜接口失败", e);
            return false;
        }
    }

    private boolean collectBiliBili() {
        String url = "https://api.bilibili.com/x/web-interface/wbi/search/square?limit=10&platform=web&web_location=333.1007&w_rid=930cac2d52dc74993837ffe44072865d&wts=1753077427";

        HttpRequest httpRequest = HttpRequest.get(url)
                .header("authority", "api.bilibili.com")
                .header("accept", "*/*")
                .header("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("origin", "https://www.bilibili.com")
                .header("referer", "https://www.bilibili.com/")
                .header("sec-ch-ua", "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Microsoft Edge\";v=\"114\"")
                .header("sec-ch-ua-mobile", "?0")
                .header("sec-ch-ua-platform", "\"Windows\"")
                .header("sec-fetch-dest", "empty")
                .header("sec-fetch-mode", "cors")
                .header("sec-fetch-site", "same-site")
                .header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.51")
                .header("Cookie", "buvid3=A7EDD27C-8E7F-EDB2-62D0-3D41B4663C8C11654infoc; b_nut=1753077411; b_lsid=23EDBE41_1982B8E712B; bsource=search_baidu; _uuid=51013BF510-3DFC-5F24-68D6-842B8E4EAD6812172infoc; enable_web_push=DISABLE; home_feed_column=5; buvid4=6327BE27-2EED-1A11-4F4F-25E4D37722E415203-025072113-HI/AtnsVFGEh0DYZY4KrkA%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTMzMzY2MTQsImlhdCI6MTc1MzA3NzM1NCwicGx0IjotMX0.zDzA97uN_AUfTNvHW5eaNfEZNtBJEQSUiSRYi3rXSIQ; bili_ticket_expires=1753336554; buvid_fp=9393036592ffbdfafa534beacfc3166e; browser_resolution=1482-388")
                .timeout(30000);

        try (HttpResponse response = httpRequest.execute()) {
            int status = response.getStatus();
            String body = response.body();

            log.info("请求哔哩哔哩热搜接口，状态码:[{}], 响应内容长度:[{}]", status, body.length());

            if (status == 200) {
                JSONObject bodyJsonObject = JSON.parseObject(body);
                if (NumberUtils.INTEGER_ZERO.equals(bodyJsonObject.getInteger("code"))) {
                    JSONArray trendJsonArray = (JSONArray) bodyJsonObject.getByPath("data.trending.list");
                    for (int i = 0; i < trendJsonArray.size(); i++) {
                        JSONObject trendJsonObject = trendJsonArray.getJSONObject(i);
                        long score = NumberConvertUtils.convertToLong(trendJsonObject.getString("heat_score"));
                        if (score > 0) {
                            String keyword = trendJsonObject.getString("show_name");
                            Integer rank = i + 1;
                            String link = String.format("https://search.bilibili.com/all?keyword=%s", URLEncoder.encode(keyword, StandardCharsets.UTF_8));
                            String image = "";

                            assignHotRecord("1952311031668051969", keyword, keyword, link, score, rank, image, trendJsonObject.toString());
                        }
                    }
                }
            }

            return status == 200;
        } catch (Exception e) {
            log.error("请求哔哩哔哩热搜接口失败", e);
            return false;
        }
    }

    private void assignHotRecord(String platformId, String title, String summary, String link, long score, Integer rank, String image, String rawContent) {
        HotRecord hotRecord = new HotRecord();
        hotRecord.setRecordId(IdWorker.getIdStr());
        hotRecord.setPlatformId(platformId);
        hotRecord.setKeyword(title);
        hotRecord.setTitle(title);
        hotRecord.setSummary(summary);
        hotRecord.setLink(link);
        hotRecord.setScore(score);
        hotRecord.setRank(rank);
        hotRecord.setRawImage(image);
        hotRecord.setRawContent(rawContent);
        hotRecord.setStatus(NumberUtils.INTEGER_MINUS_ONE.toString());
        hotRecord.setCreateBy("admin");
        hotRecord.setCreateTime(LocalDateTime.now());
        hotRecord.setUpdateBy("admin");
        hotRecord.setUpdateTime(LocalDateTime.now());
        insertOrUpdate(hotRecord);
    }

    /**
     * 从HTML中提取JSON数据
     * @param html HTML内容
     * @return 提取的JSON字符串
     */
    private String extractJsonFromHtml(String html) {
        if (StringUtils.isBlank(html)) {
            return null;
        }

        // 查找包含视频数据的JSON部分
        String startMarker = "window.__PRELOADED_STATE__ = ";
        String endMarker = "</script>";

        int startIndex = html.indexOf(startMarker);
        if (startIndex == -1) {
            return null;
        }

        startIndex += startMarker.length();
        int endIndex = html.indexOf(endMarker, startIndex);
        if (endIndex == -1) {
            return null;
        }

        String jsonStr = html.substring(startIndex, endIndex).trim();
        // 移除末尾可能存在的分号
        if (jsonStr.endsWith(";")) {
            jsonStr = jsonStr.substring(0, jsonStr.length() - 1);
        }

        return jsonStr;
    }


    private void insertOrUpdate(HotRecord hotRecord) {
        LambdaQueryWrapper<HotRecord> qWrapper = new LambdaQueryWrapper<HotRecord>()
                .eq(HotRecord::getKeyword, hotRecord.getKeyword())
                .eq(HotRecord::getPlatformId, hotRecord.getPlatformId());
        HotRecord dbOne = getOne(qWrapper);
        if (dbOne == null) {
            save(hotRecord);
        } else {
            LambdaUpdateWrapper<HotRecord> uWrapper = new LambdaUpdateWrapper<HotRecord>();
            uWrapper.eq(HotRecord::getRecordId, dbOne.getRecordId());
            uWrapper.set(HotRecord::getScore, hotRecord.getScore());
            uWrapper.set(HotRecord::getRank, hotRecord.getRank());
            uWrapper.set(HotRecord::getUpdateBy, hotRecord.getUpdateBy());
            uWrapper.set(HotRecord::getUpdateTime, hotRecord.getUpdateTime());
            update(uWrapper);
        }
    }

    /**
     * 使用Selenium获取网页中的JSON数据
     * @param url 网页地址
     * @return 解析后的JSON对象
     */
    public boolean collectWithSelenium(String url) {
        WebDriver driver = null;
        try {
            System.setProperty("webdriver.chrome.driver", "D:/chromedriver/chromedriver-137.0.7151.69.exe");
            ChromeOptions options = new ChromeOptions();
//            options.addArguments("--headless");
            options.addArguments("--no-sandbox");
            options.addArguments("--disable-dev-shm-usage");

            options.setExperimentalOption("useAutomationExtension", false);
            options.addArguments("--disable-blink-features=AutomationControlled");

            driver = new ChromeDriver(options);
            driver.get(url);

            try {
                // 等待页面加载完成
                WebDriverWait waitPage = new WebDriverWait(driver, Duration.ofSeconds(10));

                // 查找class为"winE-policy-close-b"的div元素
                WebElement closeButton = waitPage.until(
                    ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='winE-policy-close-b']"))
                );

                // 点击关闭按钮
                closeButton.click();
            } catch (Exception e) {
                log.error("关闭按钮点击异常", e);
            }

            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                log.warn("等待过程中被中断", e);
                Thread.currentThread().interrupt();
            }

            // 向下滑动2个屏幕高度
            JavascriptExecutor windowJs = (JavascriptExecutor) driver;
            windowJs.executeScript("window.scrollBy(0, window.innerHeight * 2);");

            List<WebElement> elements = driver.findElements(By.xpath("//div[@class='public']"));
            for (WebElement publicElement : elements) {
                try {
                    // 查找当前publicElement下class为comH-t-title的div元素
                    WebElement titleElement = publicElement.findElement(By.xpath(".//div[@class='comH-t-title']"));
                    // 获取该元素的文本内容并判断是否为"热门视频"
                    String innerText = titleElement.getText();
                    if ("热门视频".equals(innerText)) {
                        // 获取当前publicElement下class为"comH-item-a tobigBox"的div列表
                        List<WebElement> itemElements = publicElement.findElements(By.xpath(".//div[@class='comH-item-a tobigBox']"));
                        int rank = 1;
                        for (WebElement itemElement : itemElements) {
                            try {
                                // 获取当前itemElement下class为"comH-item-a-fullTitle"的div的innerText
                                WebElement titleDiv = itemElement.findElement(By.xpath(".//div[@class='comH-item-a-fullTitle']"));
                                String keyword = titleDiv.getAttribute("innerText");

                                // 获取当前itemElement下的img标签
                                WebElement imgElement = itemElement.findElement(By.xpath(".//div[@class='comH-item-a-cover']/img"));
                                String image = imgElement.getAttribute("data-src");

                                System.out.printf("标题:[%s], 图片地址:[%s]%n", keyword, image);

                                // 使用JavaScript点击元素，避免被遮挡
                                try {
                                    // 等待元素可点击
                                    WebDriverWait waitItem = new WebDriverWait(driver, Duration.ofSeconds(10));
                                    waitItem.until(ExpectedConditions.elementToBeClickable(itemElement));

                                    // 滚动元素到视图中心
                                    JavascriptExecutor itemJs = (JavascriptExecutor) driver;
                                    itemJs.executeScript("arguments[0].scrollIntoView({block: 'center', behavior: 'smooth'});", itemElement);

                                    // 等待滚动完成
                                    Thread.sleep(500);

                                    // 尝试直接点击
                                    itemElement.click();
                                } catch (ElementClickInterceptedException e) {
                                    log.warn("直接点击被拦截，使用JavaScript执行点击");
                                    JavascriptExecutor executor = (JavascriptExecutor) driver;
                                    executor.executeScript("arguments[0].click();", itemElement);
                                } catch (Exception e) {
                                    log.error("点击元素时发生异常", e);
                                    // 即使点击失败也继续执行后续操作
                                }

                                // 等待新窗口出现
                                WebDriverWait waitItem = new WebDriverWait(driver, Duration.ofSeconds(10));
                                waitItem.until(ExpectedConditions.numberOfWindowsToBe(2));

                                // 获取所有窗口句柄
                                Set<String> windowHandles = driver.getWindowHandles();
                                Iterator<String> iterator = windowHandles.iterator();

                                // 获取原始窗口句柄
                                String originalWindow = iterator.next();
                                String newWindow = iterator.next();

                                // 切换到新标签页
                                driver.switchTo().window(newWindow);

                                // 获取新标签页的URL
                                String link = driver.getCurrentUrl();
                                System.out.println("新标签页地址: " + link);

                                // 获取class="video-main-l-title"的div下的class="title overflow-1"的div的html
                                String summary = "";
                                try {
                                    WebElement videoMainTitle = driver.findElement(By.xpath("//div[@class='video-main-l-title']"));
                                    WebElement videoTitleElement = videoMainTitle.findElement(By.xpath(".//div[@class='title overflow-1']"));
                                    summary = videoTitleElement.getAttribute("innerHTML");
                                    System.out.println("标题VideoTitleHtml内容: " + summary);
                                } catch (NoSuchElementException e) {
                                    log.warn("未找到指定的标题元素");
                                } catch (Exception e) {
                                    log.error("获取标题元素HTML时发生异常", e);
                                }

                                assignHotRecord("1954737312458473473", keyword, summary, link, 0, rank, image, new JSONObject().toString());

                                Thread.sleep(10000);

                                if (rank == 5) {
                                    try {
                                        // 查找并点击publicElement元素下class="comH-t-r-l-rimg ron"的div
                                        WebElement nextElement = publicElement.findElement(By.xpath(".//div[@class='comH-t-r-l-rimg ron']"));

                                        // 使用JavaScript点击避免被遮挡
                                        JavascriptExecutor executor = (JavascriptExecutor) driver;
                                        executor.executeScript("arguments[0].scrollIntoView({block: 'center', behavior: 'smooth'});", nextElement);
                                        Thread.sleep(500);
                                        executor.executeScript("arguments[0].click();", nextElement);

                                        System.out.println("已点击下一页元素");
                                    } catch (NoSuchElementException e) {
                                        log.warn("未找到下一页元素");
                                    } catch (Exception e) {
                                        log.error("点击下一页元素时发生异常", e);
                                    }
                                }

                                rank++;
                                // 关闭新标签页并切换回原始页面
                                driver.close();
                                driver.switchTo().window(originalWindow);
                            } catch (Exception e) {
                                log.error("处理热门视频Item异常", e);
                            }
                        }

                        return true;
                    }
                } catch (NoSuchElementException e) {
                    // 元素不存在，跳过当前循环
                    log.error("元素不存在, innerHTML:[{}]", publicElement.getAttribute("innerHTML"), e);
                }
            }
            return true;
        } catch (Exception e) {
            log.error("使用Selenium提取页面数据失败，URL:[{}]", url, e);
            return false;
        } finally {
//            if (driver != null) {
//                try {
//                    driver.quit();
//                } catch (Exception e) {
//                    log.error("关闭WebDriver失败", e);
//                }
//            }
        }
    }


}
